package com.cjx.minio.controller;

import cn.hutool.core.util.StrUtil;
import com.cjx.common.api.CommonResult;
import com.cjx.common.exception.Asserts;
import com.cjx.minio.api.FileManagementService;
import com.cjx.minio.dto.FileManagementDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 *@Author cjunxian
 * @version 1.0.0
 * @date 2020/09/25 16:52:24
 * @doc 文件管理Controller层
 */
@Api(tags = "文件管理服务接口", value = "FileManagementController")
@RestController
@RequestMapping("/fileManagement")
public class FileManagementController {

    @Autowired
    FileManagementService fileManagementService;

    /**
     * 上传文件
     *
     * @param file       文件对象
     * @param userId     用户id
     * @param canPreview 是否可预览
     * @return 文件管理对象
     */
    @ApiOperation(value = "上传文件")
    @ApiImplicitParams(
            value = {
                    @ApiImplicitParam(name = "file", value = "上传的文件", dataType = "MultipartFile"),
                    @ApiImplicitParam(name = "userId", value = "用户id", dataType = "String"),
                    @ApiImplicitParam(
                            name = "canPreview",
                            value = "是否需要预览: 0->不可以预览; 1->可以预览",
                            dataType = "Long",
                            defaultValue = "0")
            })
    @PostMapping("/uploadFile")
    public CommonResult<FileManagementDTO> uploadFile(@RequestParam MultipartFile file,@RequestParam String userId,@RequestParam(required = false,defaultValue = "1") Long canPreview) {
        return CommonResult.success(fileManagementService.saveFile(file, userId, canPreview));
    }

    /**
     * 上传多个文件
     *
     * @param files      文件数组
     * @param userId     用户id
     * @param canPreview 是否可预览
     * @return 文件管理对象列表
     */
    @ApiOperation(value = "上传一个或多个文件", notes = "无法在swagger测试上传文件，协议问题")
    @PostMapping(value = "/uploadFiles")
    @ApiImplicitParams(
            value = {
                    @ApiImplicitParam(name = "files", value = "上传的文件", dataType = "MultipartFile[]"),
                    @ApiImplicitParam(name = "userId", value = "用户id", dataType = "String"),
                    @ApiImplicitParam(
                            name = "canPreview",
                            value = "是否需要预览: 0->不可以预览; 1->可以预览",
                            dataType = "Long",
                            defaultValue = "0")
            })
    public CommonResult<List<FileManagementDTO>> uploadFiles(MultipartFile[] files,@RequestParam String userId,@RequestParam(required = false,defaultValue = "1") Long canPreview) {
        return CommonResult.success(fileManagementService.saveFiles(files, userId, canPreview));
    }

    /**
     * 下载
     *
     * @param fileId   文件管理id
     * @param response 响应对象
     */
    @ApiOperation(value = "下载")
    @GetMapping("/downloadFile/{fileId}")
    @ApiImplicitParams(
            value = {@ApiImplicitParam(name = "fileId", value = "文件id", dataType = "String")})
    public CommonResult downloadFile(@PathVariable String fileId, HttpServletResponse response) {
        boolean success = fileManagementService.downloadFile2Stream(fileId, response);
        if (!success) {
            return CommonResult.failed("文件下载出错");
        }
        return CommonResult.success(null);
    }



    /**
     * 下载多个，会生成zip压缩文件
     *
     * @param fileIds  文件管理ids,文件id以逗号分隔
     * @param response 响应对象
     */
    @ApiOperation(value = "下载多个，会生成zip压缩文件")
    @GetMapping("/download2Zip/{fileIds}")
    @ApiImplicitParams(
            value = {@ApiImplicitParam(name = "fileIds", value = "文件id,用逗号分隔", dataType = "String")})
    public CommonResult download2Zip(@PathVariable String fileIds, HttpServletResponse response) {
        if (StrUtil.isEmpty(fileIds)) {
            Asserts.fail("下载文件Id为空！");
        }
        List<String> fileIdList =
                Arrays.stream(fileIds.split(","))
                        .map(s -> s.trim())
                        .collect(Collectors.toList());
        boolean success = fileManagementService.downloadFiles2Zip(fileIdList, response);
        if (!success) {
            return CommonResult.failed("文件下载出错");
        }
        return CommonResult.success(null);
    }

    /**
     * 获取文件信息
     *
     * @param fileId 文件管理id
     * @return 文件管理对象
     */
    @ApiOperation(value = "获取文件信息")
    @GetMapping("/getFileManagementById")
    @ApiImplicitParams(
            value = {@ApiImplicitParam(name = "fileId", value = "文件id", dataType = "String")})
    public CommonResult getFileManagementById(@RequestParam String fileId) {
        return CommonResult.success(fileManagementService.getFileManagementById(fileId));
    }

    /**
     * 获取多个文件信息
     *
     * @param fileIds 文件管理ids
     * @return 文件管理对象列表
     */
    @ApiOperation(value = "获取一个或多个文件信息")
    @ApiImplicitParams(
            value = {@ApiImplicitParam(name = "fileIds", value = "文件id,用逗号分隔", dataType = "String")})
    @GetMapping("/fileInfo/{fileIds}")
    public CommonResult getFileManagementByIds(@PathVariable String fileIds) {
        if (StrUtil.isEmpty(fileIds)) {
            Asserts.fail("下载文件Id为空！");
        }
        List<String> fileIdList =
                Arrays.stream(fileIds.split(","))
                        .map(s ->s.trim())
                        .collect(Collectors.toList());
        return CommonResult.success(fileManagementService.getFileManagementByIds(fileIdList));
    }

    /**
     * 删除文件
     *
     * @param fileId 文件管理id
     * @return the result
     */
    @ApiOperation(value = "删除记录")
    @DeleteMapping("/deleteFileManagementById")
    @ApiImplicitParams(
            value = {@ApiImplicitParam(name = "fileId", value = "文件id", dataType = "String")})
    public CommonResult deleteFileManagementById(@RequestParam String fileId) {
        boolean success = fileManagementService.deleteFileManagementById(fileId);
        if (!success) {
            return CommonResult.failed("文件删除出错！");
        }
        return CommonResult.success("文件删除成功！");
    }

    /**
     * 删除多个文件
     *
     * @param fileIds 文件管理ids
     */
    @ApiOperation(value = "删除记录，多条记录使用逗号分隔")
    @DeleteMapping("/deleteFileManagementByIds")
    @ApiImplicitParams(
            value = {@ApiImplicitParam(name = "fileIds", value = "文件id,用逗号分隔", dataType = "String")})
    public CommonResult deleteFileManagementByIds(@RequestParam String fileIds) {
        if (StrUtil.isEmpty(fileIds)) {
            Asserts.fail("下载文件Id为空！");
        }
        List<String> fileIdList =
                Arrays.stream(fileIds.split(","))
                        .map(s -> s.trim())
                        .collect(Collectors.toList());
        boolean success = fileManagementService.deleteFileManagementByIds(fileIdList);
        if (!success) {
            return CommonResult.failed("文件删除出错！");
        }
        return CommonResult.success("文件删除成功！");
    }

    /**
     * 上传视频文件 ffmpeg处理
     *
     * @param file       文件对象
     * @param userId     用户id
     * @param canPreview 是否可预览
     * @return 文件管理对象
     */
    @ApiOperation(value = "上传视频文件", hidden = true)
    @ApiImplicitParams(
            value = {
                    @ApiImplicitParam(name = "file", value = "上传的文件", dataType = "MultipartFile"),
                    @ApiImplicitParam(name = "userId", value = "用户id", dataType = "String"),
                    @ApiImplicitParam(
                            name = "canPreview",
                            value = "是否需要预览: 0->不可以预览; 1->可以预览",
                            dataType = "Long",
                            defaultValue = "0")
            })
    @PostMapping("/uploadVideoFile")
    public CommonResult<FileManagementDTO> saveVideoFile(@RequestParam MultipartFile file,@RequestParam String userId,@RequestParam(required = false,defaultValue = "1") Long canPreview) {
        return CommonResult.success(fileManagementService.saveVideoFile(file, userId, canPreview));
    }

    /**
     * 异步上传视频文件 jave处理
     *
     * @param file       文件对象
     * @param userId     用户id
     * @param canPreview 是否可预览
     * @return 文件管理对象
     */
    @ApiOperation(value = "异步上传视频文件,需要先进行websocket连接（仅avi,flv,mp4）")
    @ApiImplicitParams(
            value = {
                    @ApiImplicitParam(name = "file", value = "上传的文件", dataType = "MultipartFile"),
                    @ApiImplicitParam(name = "userId", value = "用户id", dataType = "String"),
                    @ApiImplicitParam(
                            name = "canPreview",
                            value = "是否需要预览: 0->不可以预览; 1->可以预览",
                            dataType = "Long",
                            defaultValue = "0")
            })
    @PostMapping("/uploadMediaFile")
    public CommonResult<String> saveMediaFile(@RequestParam MultipartFile file,@RequestParam String userId,@RequestParam(required = false,defaultValue = "1") Long canPreview) throws IOException {
        //记录时哪个视频任务
        String fileName = file.getOriginalFilename();
        InputStream inputStream = file.getInputStream();
        List<FileManagementDTO> fileList = new ArrayList<>();
        fileManagementService.saveMediaFile(fileName, inputStream,userId, canPreview,fileList);
        return CommonResult.success("用户" + userId + "正在进行" + fileName + "视频解析...");
    }


    /**
     * 在线读取zip文件并上传
     * @param file zip文件
     * @param userId 用户id
     * @return 文件管理对象集合
     */
    @ApiOperation(value = "在线读取zip文件并上传")
    @ApiImplicitParams(
            value = {
                    @ApiImplicitParam(name = "file", value = "上传的文件", dataType = "MultipartFile"),
                    @ApiImplicitParam(name = "userId", value = "用户id", dataType = "String")
            })
    @PostMapping("/readZipFile")
    public CommonResult<List<FileManagementDTO>> readZip(MultipartFile file,@RequestParam String userId){
        return CommonResult.success(fileManagementService.readZipFile(file,userId));
    }
}
